package org.Yiran.timetale_re.datagen;

import net.minecraft.advancements.critereon.InventoryChangeTrigger;
import net.minecraft.data.recipes.FinishedRecipe;
import net.minecraft.data.recipes.RecipeCategory;
import net.minecraft.data.recipes.ShapedRecipeBuilder;
import net.minecraft.data.recipes.ShapelessRecipeBuilder;
import net.minecraft.data.recipes.SimpleCookingRecipeBuilder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Ingredient;
import org.Yiran.timetale_re.Timetale_re;
import org.Yiran.timetale_re.item.MaterialRegister;
import org.Yiran.timetale_re.item.MaterialRegister.MaterialDefinition;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * 材料配方提供器类，用于注册材料相关配方
 * <p>
 * 该类负责生成游戏中所有材料相关的合成配方和烧制配方，包括：
 * 1. 粒、锭、块之间的相互转换配方
 * 2. 粗矿到锭的烧制配方
 * 3. 粉末到锭的烧制配方
 * 4. 配方JSON数据的生成
 * </p>
 */
public class MaterialRecipeProvider {
    
    // ============================== 配方注册方法 ==============================
    
    /**
     * 注册所有材料的配方
     * <p>
     * 遍历所有已注册的材料，为每种材料生成相应的合成配方
     * </p>
     * 
     * @param consumer 配方消费者，用于接收生成的配方
     */
    public static void registerAllMaterialRecipes(Consumer<FinishedRecipe> consumer) {
        System.out.println("开始注册所有材料配方...");
        int materialCount = MaterialRegister.getRegisteredMaterials().size();
        System.out.println("共有 " + materialCount + " 种材料需要注册配方");
        
        MaterialRegister.getRegisteredMaterials().forEach(material -> registerMaterialRecipes(consumer, material));
        
        System.out.println("材料配方注册完成!");
    }
    
    /**
     * 注册特定材料的合成配方
     * <p>
     * 为指定材料生成以下配方（如果适用）：
     * 1. 9个粒合成1个锭
     * 2. 9个锭合成1个块
     * 3. 1个块分解成9个锭
     * 4. 1个锭分解成9个粒
     * 5. 9个粗矿合成1个粗矿块
     * 6. 1个粗矿块分解成9个粗矿
     * </p>
     * 
     * @param consumer 配方消费者，用于接收生成的配方
     * @param material 材料定义对象，包含该材料的所有相关信息
     */
    public static void registerMaterialRecipes(Consumer<FinishedRecipe> consumer, MaterialDefinition material) {
        System.out.println("开始为材料 \"" + material.getName() + "\" 注册合成配方...");
        int recipeCount = 0;

        // 注册9个粒合成1个锭的配方
        if (material.getNugget() != null && material.getIngot() != null) {
            ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, material.getIngot().get())
                    .requires(material.getNugget().get(), 9)
                    .unlockedBy("has_" + material.getName() + "_nugget",
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getNugget().get()))
                    .save(consumer, ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                            material.getName() + "_ingot_from_nuggets"));
            System.out.println("  已注册: 9个" + material.getName() + "粒 -> 1个" + material.getName() + "锭");
            recipeCount++;
        }

        // 注册9个锭合成1个块的配方
        if (material.getIngot() != null && material.getBlockItem() != null) {
            ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, material.getBlockItem().get())
                    .define('#', material.getIngot().get())
                    .pattern("###")
                    .pattern("###")
                    .pattern("###")
                    .unlockedBy("has_" + material.getName() + "_ingot",
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getIngot().get()))
                    .save(consumer, ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                            material.getName() + "_block_from_ingots"));
            System.out.println("  已注册: 9个" + material.getName() + "锭 -> 1个" + material.getName() + "块");
            recipeCount++;
        }

        // 注册1个块分解成9个锭的配方
        if (material.getBlockItem() != null && material.getIngot() != null) {
            ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, material.getIngot().get(), 9)
                    .requires(material.getBlockItem().get())
                    .unlockedBy("has_" + material.getName() + "_block",
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getBlockItem().get()))
                    .save(consumer, ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                            material.getName() + "_ingot_from_block"));
            System.out.println("  已注册: 1个" + material.getName() + "块 -> 9个" + material.getName() + "锭");
            recipeCount++;
        }

        // 注册1个锭分解成9个粒的配方
        if (material.getIngot() != null && material.getNugget() != null) {
            ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, material.getNugget().get(), 9)
                    .requires(material.getIngot().get())
                    .unlockedBy("has_" + material.getName() + "_ingot",
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getIngot().get()))
                    .save(consumer, ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                            material.getName() + "_nugget_from_ingot"));
            System.out.println("  已注册: 1个" + material.getName() + "锭 -> 9个" + material.getName() + "粒");
            recipeCount++;
        }

        // 注册9个粗矿合成1个粗矿块的配方
        if (material.hasRawBlock() && material.getRaw() != null && material.getRawBlockItem() != null) {
            ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, material.getRawBlockItem().get())
                    .define('#', material.getRaw().get())
                    .pattern("###")
                    .pattern("###")
                    .pattern("###")
                    .unlockedBy("has_raw_" + material.getName(),
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getRaw().get()))
                    .save(consumer, ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                            "raw_" + material.getName() + "_block_from_raw"));
            System.out.println("  已注册: 9个粗" + material.getName() + "矿 -> 1个粗" + material.getName() + "矿块");
            recipeCount++;
        }

        // 注册1个粗矿块分解成9个粗矿的配方
        if (material.hasRawBlock() && material.getRaw() != null && material.getRawBlockItem() != null) {
            ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, material.getRaw().get(), 9)
                    .requires(material.getRawBlockItem().get())
                    .unlockedBy("has_raw_" + material.getName() + "_block",
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getRawBlockItem().get()))
                    .save(consumer, ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                            "raw_" + material.getName() + "_from_raw_block"));
            System.out.println("  已注册: 1个粗" + material.getName() + "矿块 -> 9个粗" + material.getName() + "矿");
            recipeCount++;
        }
        
        System.out.println("材料 \"" + material.getName() + "\" 共注册了 " + recipeCount + " 个合成配方");
    }
    
    // ============================== 烧制配方注册方法 ==============================
    
    /**
     * 注册所有材料的烧制配方
     * <p>
     * 遍历所有已注册的材料，为每种材料生成相应的烧制配方
     * </p>
     * 
     * @param consumer 配方消费者，用于接收生成的配方
     */
    public static void registerAllSmeltingRecipes(Consumer<FinishedRecipe> consumer) {
        System.out.println("开始注册所有材料烧制配方...");
        int materialCount = MaterialRegister.getRegisteredMaterials().size();
        System.out.println("共有 " + materialCount + " 种材料需要注册烧制配方");
        
        MaterialRegister.getRegisteredMaterials().forEach(material -> registerSmeltingRecipes(consumer, material));
        
        System.out.println("材料烧制配方注册完成!");
    }
    
    /**
     * 注册特定材料的烧制配方
     * <p>
     * 为指定材料生成以下烧制配方（如果适用）：
     * 1. 粗矿到锭的烧制配方（普通炉和高炉）
     * 2. 粉末到锭的烧制配方（普通炉和高炉）
     * </p>
     * 
     * @param consumer 配方消费者，用于接收生成的配方
     * @param material 材料定义对象，包含该材料的所有相关信息
     */
    public static void registerSmeltingRecipes(Consumer<FinishedRecipe> consumer, MaterialDefinition material) {
        System.out.println("开始为材料 \"" + material.getName() + "\" 注册烧制配方...");
        int recipeCount = 0;

        // 检查是否需要注册烧制配方
        if (material.hasSmeltingRecipe() && material.getRaw() != null && material.getIngot() != null) {
            // 注册粗矿到锭的烧制配方
            SimpleCookingRecipeBuilder.smelting(
                            Ingredient.of(material.getRaw().get()),
                            RecipeCategory.MISC,
                            material.getIngot().get(),
                            material.getSmeltingExperience(),
                            material.getSmeltingTime()
                    ).unlockedBy(
                            "has_raw_" + material.getName(),
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getRaw().get()))
                    .save(
                            consumer,
                            ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                                    material.getName() + "_ingot_from_smelting_raw")
                    );
            System.out.println("  已注册: 粗" + material.getName() + "矿 -> " + material.getName() + "锭 (普通炉)");
            recipeCount++;

            // 注册粗矿到锭的高炉烧制配方（如果需要）
            SimpleCookingRecipeBuilder.blasting(
                            Ingredient.of(material.getRaw().get()),
                            RecipeCategory.MISC,
                            material.getIngot().get(),
                            material.getSmeltingExperience(),
                            material.getSmeltingTime() / 2
                    ).unlockedBy(
                            "has_raw_" + material.getName(),
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getRaw().get()))
                    .save(
                            consumer,
                            ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                                    material.getName() + "_ingot_from_blasting_raw")
                    );
            System.out.println("  已注册: 粗" + material.getName() + "矿 -> " + material.getName() + "锭 (高炉)");
            recipeCount++;
        }

        // 新增：注册粉到锭的烧制配方
        if (material.hasDust() && material.getDust() != null && material.getIngot() != null) {
            // 注册粉到锭的烧制配方
            SimpleCookingRecipeBuilder.smelting(
                            Ingredient.of(material.getDust().get()),
                            RecipeCategory.MISC,
                            material.getIngot().get(),
                            material.getSmeltingExperience(),
                            material.getSmeltingTime() / 3
                    ).unlockedBy(
                            "has_" + material.getName() + "_dust",
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getDust().get()))
                    .save(
                            consumer,
                            ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                                    material.getName() + "_ingot_from_smelting_dust")
                    );
            System.out.println("  已注册: " + material.getName() + "粉 -> " + material.getName() + "锭 (普通炉)");
            recipeCount++;

            // 注册粉到锭的高炉烧制配方
            SimpleCookingRecipeBuilder.blasting(
                            Ingredient.of(material.getDust().get()),
                            RecipeCategory.MISC,
                            material.getIngot().get(),
                            material.getSmeltingExperience(),
                            material.getSmeltingTime() / 6
                    ).unlockedBy(
                            "has_" + material.getName() + "_dust",
                            InventoryChangeTrigger.TriggerInstance.hasItems(material.getDust().get()))
                    .save(
                            consumer,
                            ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID,
                                    material.getName() + "_ingot_from_blasting_dust")
                    );
            System.out.println("  已注册: " + material.getName() + "粉 -> " + material.getName() + "锭 (高炉)");
            recipeCount++;
        }
        
        System.out.println("材料 \"" + material.getName() + "\" 共注册了 " + recipeCount + " 个烧制配方");
    }
    
    // ============================== JSON配方生成方法 ==============================
    
    /**
     * 生成材料配方的JSON表示形式
     * <p>
     * 为指定材料生成配方的JSON字符串表示，用于调试或文档目的
     * </p>
     * 
     * @param material 材料定义对象，包含该材料的所有相关信息
     * @return 包含该材料所有配方JSON字符串的列表
     */
    public static List<String> generateMaterialRecipeJsons(MaterialDefinition material) {
        System.out.println("开始为材料 \"" + material.getName() + "\" 生成配方JSON...");
        List<String> jsonRecipes = new ArrayList<>();
        int jsonCount = 0;

        // 生成9个粒合成1个锭的配方JSON
        if (material.getNugget() != null && material.getIngot() != null) {
            StringBuilder nuggetToIngotRecipeBuilder = new StringBuilder();
            nuggetToIngotRecipeBuilder.append("{\n")
                    .append("  \"type\": \"minecraft:crafting_shapeless\",\n")
                    .append("  \"category\": \"misc\",\n")
                    .append("  \"ingredients\": [\n");

            // 使用循环添加9个粒
            for (int i = 0; i < 9; i++) {
                nuggetToIngotRecipeBuilder.append("    {\n")
                        .append("      \"item\": \"")
                        .append(Timetale_re.MODID)
                        .append(":")
                        .append(material.getName())
                        .append("_nugget\"\n")
                        .append("    }");
                // 如果不是最后一个元素，添加逗号
                if (i < 8) {
                    nuggetToIngotRecipeBuilder.append(",\n");
                } else {
                    nuggetToIngotRecipeBuilder.append("\n");
                }
            }

            nuggetToIngotRecipeBuilder.append("  ],\n")
                    .append("  \"result\": {\n")
                    .append("    \"item\": \"")
                    .append(Timetale_re.MODID)
                    .append(":")
                    .append(material.getName())
                    .append("_ingot\"\n")
                    .append("  }\n")
                    .append("}");
            jsonRecipes.add(nuggetToIngotRecipeBuilder.toString());
            jsonCount++;
        }

        // 生成9个锭合成1个块的配方JSON
        if (material.getIngot() != null && material.getBlockItem() != null) {
            String ingotToBlockRecipe = "{\n" +
                    "  \"type\": \"minecraft:crafting_shaped\",\n" +
                    "  \"category\": \"building\",\n" +
                    "  \"pattern\": [\n" +
                    "    \"###\",\n" +
                    "    \"###\",\n" +
                    "    \"###\"\n" +
                    "  ],\n" +
                    "  \"key\": {\n" +
                    "    \"#\": {\n" +
                    "      \"item\": \"" + Timetale_re.MODID + ":" + material.getName() + "_ingot\"\n" +
                    "    }\n" +
                    "  },\n" +
                    "  \"result\": {\n" +
                    "    \"item\": \"" + Timetale_re.MODID + ":" + material.getName() + "_block\"\n" +
                    "  }\n" +
                    "}";
            jsonRecipes.add(ingotToBlockRecipe);
            jsonCount++;
        }

        // 生成1个块分解成9个锭的配方JSON
        if (material.getBlockItem() != null && material.getIngot() != null) {
            String blockToIngotRecipe = "{\n" +
                    "  \"type\": \"minecraft:crafting_shapeless\",\n" +
                    "  \"category\": \"misc\",\n" +
                    "  \"ingredients\": [\n" +
                    "    {\n" +
                    "      \"item\": \"" + Timetale_re.MODID + ":" + material.getName() + "_block\"\n" +
                    "    }\n" +
                    "  ],\n" +
                    "  \"result\": {\n" +
                    "    \"item\": \"" + Timetale_re.MODID + ":" + material.getName() + "_ingot\",\n" +
                    "    \"count\": 9\n" +
                    "  }\n" +
                    "}";
            jsonRecipes.add(blockToIngotRecipe);
            jsonCount++;
        }

        // 生成1个锭分解成9个粒的配方JSON
        if (material.getIngot() != null && material.getNugget() != null) {
            String ingotToNuggetRecipe = "{\n" +
                    "  \"type\": \"minecraft:crafting_shapeless\",\n" +
                    "  \"category\": \"misc\",\n" +
                    "  \"ingredients\": [\n" +
                    "    {\n" +
                    "      \"item\": \"" + Timetale_re.MODID + ":" + material.getName() + "_ingot\"\n" +
                    "    }\n" +
                    "  ],\n" +
                    "  \"result\": {\n" +
                    "    \"item\": \"" + Timetale_re.MODID + ":" + material.getName() + "_nugget\",\n" +
                    "    \"count\": 9\n" +
                    "  }\n" +
                    "}";
            jsonRecipes.add(ingotToNuggetRecipe);
            jsonCount++;
        }
        
        System.out.println("材料 \"" + material.getName() + "\" 共生成了 " + jsonCount + " 个配方JSON");

        return jsonRecipes;
    }
}